package com.spirngboot.middleware.middleware_rabbitmq.server.rabbitmq.direct;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Producer {

    private static final Logger log = LoggerFactory.getLogger(Producer.class);

    //所有的中间件技术都是基于tcp/ip协议基础之上构建新型的协议规范,只不过rabbitmq遵循的是amqp
    public static void main(String[] args) {
        //1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("120.24.87.40");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("root");
        connectionFactory.setPassword("Guet@207");
        connectionFactory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //2.创建连接Connection
            String connectName = "生产者";
            connection = connectionFactory.newConnection(connectName);
            log.info("创建连接成功,连接名:{},连接:{}", connectName, connection.toString());
            //3.通过连接获取通道Channel
            channel = connection.createChannel();
            log.info("创建通道成功,通道名:{}", channel.toString());
            //4.通过创建交换机,声明队列,绑定关系,路由key,发送信息和接收信息
            //5.准备交换机
            String exchangeName = "fanout-exchange";
            //6.定义路由Key
            String routingKey = "";
            //7.指定交换机的类型
            String exchangeType = "fanout";
            //8.创建交换机
            channel.exchangeDeclare(exchangeName, exchangeType);
            log.info("交换机创建完毕,交换机名:{},交换机类型为:{}", exchangeName, exchangeType);
            //9.创建队列
            String queueName = "queue-direct";
            /*
             * @param1 队列名
             * @param2 是否要持久化(非持久化也会存盘,但重启rabbitMQ后删除)
             * @param3 排他性,是否是一个独占队列
             * @param4 是否自动删除, 随着最后一个消费者消费完消息后是否把队列删除
             * @param5 携带一些附加参数
             * 第二个持久化参数和第四个自动删除的区别在于，第二是指 服务异常或重启后，队列是否还在。第四个是，如果服务正常，但队列里的消息被消费完，是否删除
             * */
            for (int i = 0; i < 3; i++) {
                String realQueueName = queueName + i;
                channel.queueDeclare(realQueueName, false, false, true, null);
                channel.queueBind(realQueueName, exchangeName, routingKey);
                log.info("创建队列成功,队列名:{},队列绑定交换机:{},交换机类型{},队列RoutingKey:{}", realQueueName, exchangeName, exchangeType, routingKey);
            }
            //10.准备消息内容
            String message = "direct-Hello, rabbitMQ!";
            //11.发送消息给队列queue
            /*
             * @param1 交换机
             * @param2 队列名
             * @param3 关于消息是否持久化等的设置
             * @param4 消息
             * */
            channel.basicPublish(exchangeName, queueName, null, message.getBytes());
            log.info("消息发送成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //7.关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //8.关闭连接
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
